package com.tian.scroll.nested_scroll.view;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
import android.widget.LinearLayout;

import androidx.annotation.Nullable;
import androidx.core.view.NestedScrollingChild;
import androidx.core.view.NestedScrollingChildHelper;
import androidx.core.view.ViewCompat;

/**
 * @author tiansongtao, Email:tiansongtao@up366.com
 * @date 2021/1/20 14:28
 */
public class NestedScrollChildLayout extends LinearLayout implements NestedScrollingChild {


    private NestedScrollingChildHelper nestedScrollingChildHelper;


    private final int[] offset = new int[2]; //偏移量
    private final int[] consumed = new int[2]; //消费


    public NestedScrollChildLayout(Context context) {
        super(context);
    }

    public NestedScrollChildLayout(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public NestedScrollChildLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

  

    public NestedScrollingChildHelper getNestedScrollingChildHelper() {
        if (nestedScrollingChildHelper == null) {
            nestedScrollingChildHelper = new NestedScrollingChildHelper(this);
            nestedScrollingChildHelper.setNestedScrollingEnabled(true);
        }
        return nestedScrollingChildHelper;
    }

    private int preX, preY;

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                preY = (int) event.getRawY();
                break;
            case MotionEvent.ACTION_MOVE:
                int dy = preY - (int) event.getRawY();
                handleMoveY(dy);
                preY = (int)event.getRawY();
                break;
            default:
                break;
        }
        return true;
    }

    private void handleMoveY(int distanceY){
        //父控件是否允许滑动
        if (startNestedScroll(ViewCompat.SCROLL_AXIS_VERTICAL)) {
            if (distanceY > 0) {
                //向上滑, 父控件先滑动子控件再滑动
                if (dispatchNestedPreScroll(0,   distanceY, consumed, offset)) {
                    //consumed为父控件消耗的距离， 未消耗的子控件继续滑动
                    int unConsumed =   distanceY - consumed[1];
                    if (unConsumed != 0) {
                        scrollBy(0, unConsumed);
                    }
                } else {
                    scrollBy(0,   distanceY);
                }
            } else {
                //向下滑， 子控件先滑动父控件后滑动
                if (getScrollY() >= 0) {
                    if (getScrollY() == 0) {
                        //子控件已不再需要滑动，父控件滑动
                        dispatchNestedScroll(0, 0, 0, distanceY, offset);
                        return ;
                    }
                    //子控件可以消耗所有滑动，先滑动自己
                    if (getScrollY() +   distanceY >= 0) {
                        scrollBy(0,   distanceY);
                    } else if (getScrollY() != 0) {
                        //子控件滑动一部分，剩余给父控件滑动
                        int consume = getScrollY();
                        int unConsumed = (int) distanceY + consume;
                        scrollTo(0, -consume);  //先自己滑动
                        dispatchNestedScroll(0, consume, 0, unConsumed, offset);
                    } else {
                        dispatchNestedScroll(0, 0, 0,   distanceY, offset);
                    }
                } else {
                    scrollTo(0, 0);
                }
            }
        }
    }

    @Override
    public boolean startNestedScroll(int axes) {
        return getNestedScrollingChildHelper().startNestedScroll(axes);
    }

    @Override
    public void stopNestedScroll() {
        super.stopNestedScroll();
        getNestedScrollingChildHelper().stopNestedScroll();
    }


    @Override
    public boolean hasNestedScrollingParent() {
        return getNestedScrollingChildHelper().hasNestedScrollingParent();
    }

    @Override
    public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, @Nullable int[] offsetInWindow) {
        return getNestedScrollingChildHelper().dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, offsetInWindow);
    }

    @Override
    public boolean dispatchNestedPreScroll(int dx, int dy, @Nullable int[] consumed, @Nullable int[] offsetInWindow) {
        return getNestedScrollingChildHelper().dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow);
    }

    @Override
    public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) {
        return getNestedScrollingChildHelper().dispatchNestedFling(velocityX, velocityY, consumed);
    }

    @Override
    public boolean dispatchNestedPreFling(float velocityX, float velocityY) {
        return getNestedScrollingChildHelper().dispatchNestedPreFling(velocityX, velocityY);
    }
}
